<template>
  <div style="height: 100%" class="tree-db-outer">
    <div class="tree-bar">
      <div style="">本地数据库</div>
      <div style="flex-grow: 1"></div>
      <div v-if="curNode && curNode.nodeType === 'folder'">
        <Button size="small" type="default" @click="exportTable" title="导出">导出</Button>
      </div>
    </div>

    <base-tree
      v-model="treeData"
      @on-select-node="selectTreeNode"
      @on-insert-node="openCreateDialog"
      @on-delete-node="deleteNode"
      style="height: calc(100% - 32px)"
      ref="baseTreeRef"
    ></base-tree>

    <load-data-dialog ref="dialogRef"></load-data-dialog>
  </div>
</template>

<script>
import { checkJsStore, insertData, createTable, dropTable } from '../base/mateDbUtil';
import BaseTree from '../components/BaseTree.vue';
import LoadDataDialog from './LoadDataDialog.vue';

export default {
  components: { LoadDataDialog, BaseTree },
  name: 'TreeDb',
  data() {
    return {
      curDbInfo: {
        name: '',
        tables: [],
        version: 1,
      },

      treeData: [
        {
          title: '',
          expand: true,
          selected: true,
          nodeIcon: 'md-filing',
          nodeType: 'root',
          // fontSize: '18px',
          // nodeId: 'root',
          children: [],
        },
      ],

      curNode: null,
    };
  },
  watch: {
    curDbInfo: {
      handler: function (params) {
        this.treeData[0].title = params.name;
        this.treeData[0].children = [];
        if (params.tables && params.tables.length > 0) {
          const tmpList = params.tables.filter(item => {
            return item.name !== 'JsStore_Meta';
          });
          tmpList.forEach(item => {
            const tmpFolder = {
              title: item.name,
              expand: false,
              nodeIcon: 'ios-list-box',
              nodeType: 'folder',
              // fontSize: '18px',
              fileInfo: item,
              children: item.columns.map(col => {
                return {
                  title: col.name,
                  expand: false,
                  nodeIcon: 'ios-cube-outline',
                  nodeType: 'file',
                  // fontSize: '18px',
                  fileInfo: col,
                  children: [],
                };
              }),
            };
            this.treeData[0].children.push(tmpFolder);
          });
        }
      },
      deep: true,
    },
  },
  methods: {
    deleteNode() {
      if (!this.curNode || this.curNode.nodeType !== 'folder') {
        return;
      }
      dropTable(this.curDbInfo, this.curNode.title).then(retObj => {
        if (retObj) {
          this.$Message.success('表删除成功: ' + retObj);
          this.initDbInfo();
        }
      });
    },
    exportTable() {
      const text = JSON.stringify(this.curNode.fileInfo, null, 2);
      const BOM = '\uFEFF';
      const fileObj = new Blob([BOM + text], { type: 'application/json' });

      let linkEle = document.createElement('a');
      linkEle.href = URL.createObjectURL(fileObj);
      linkEle.download = this.curNode.title;
      document.body.appendChild(linkEle);
      linkEle.click();
      document.body.removeChild(linkEle);
    },
    openCreateDialog() {
      this.$refs.dialogRef.openDialog('获取表结构').then(retStr => {
        const paramObj = JSON.parse(retStr);
        // 监测数据合法性
        if (!paramObj.name) {
          this.$Message.warning('表名称不合法');
          return;
        }
        if (!paramObj.columns || paramObj.columns.length === 0) {
          this.$Message.warning('表格列不合法');
          return;
        }
        createTable(this.curDbInfo, paramObj).then(retObj => {
          if (retObj) {
            this.$Message.success('表添加成功: ' + retObj);
            this.initDbInfo();
          }
        });
      });
    },

    selectTreeNode(param) {
      this.curNode = param;
      this.$emit('select-tree-node', this.curNode);
    },

    initDbInfo() {
      checkJsStore().then(retObj => {
        Object.assign(this.curDbInfo, retObj);
      });
    },
  },
  mounted() {
    this.initDbInfo();
  },
};
</script>

<style scoped>
.tree-bar {
  display: flex;
  height: 32px;
  line-height: 36px;
  background-color: #ffffff;
  padding: 0 16px;
}

.top-btn {
  /* width: 40px; */
  margin-right: 4px;
}
</style>
